package com.netty.server.handler;

import com.netty.server.base.ConnectStatus;
import com.netty.server.base.ConnectionAttr;
import com.netty.server.base.ConnectionGroup;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

import java.util.Optional;

/**
 * handlerAdded:        handler被添加到channel的pipeline
 * channelRegistered:   channel注册到NioEventLoop
 * channelActive:       channel准备就绪
 * channelRead:         channel中有可读的数据
 * channelReadComplete: channel读数据完成
 * channelReadComplete: channel读数据完成
 * channelInactive:     channel被关闭
 * channelUnregistered: channel取消和NioEventLoop的绑定
 * handlerRemoved:      handler从channel的pipeline中移除
 *
 * @author: 王霄
 * @date: 2022/1/18 10:09
 **/
@Slf4j
public class StatusHandler extends ChannelInboundHandlerAdapter {

    private final ConnectionGroup connectionGroup;

    public StatusHandler(ConnectionGroup connectionGroup) {
        this.connectionGroup = connectionGroup;
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
        ctx.channel().attr(ConnectionAttr.STATUS).set(ConnectStatus.INIT);
        log.debug(String.format("客户端处于INIT状态, remoteAddress:[%s]", ctx.channel().remoteAddress()));
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        super.channelRegistered(ctx);
        ctx.channel().attr(ConnectionAttr.STATUS).set(ConnectStatus.ACTIVATING);
        log.debug(String.format("客户端处于ACTIVATING状态, remoteAddress:[%s]", ctx.channel().remoteAddress()));
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        ctx.channel().attr(ConnectionAttr.STATUS).set(ConnectStatus.ACTIVE);
        log.debug(String.format("客户端处于ACTIVE状态, remoteAddress:[%s]", ctx.channel().remoteAddress()));
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        super.channelRead(ctx, msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        ctx.channel().attr(ConnectionAttr.STATUS).set(ConnectStatus.CLOSING);
        log.debug(String.format("客户端处于CLOSING状态, remoteAddress:[%s]", ctx.channel().remoteAddress()));
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        super.channelUnregistered(ctx);
        ctx.channel().attr(ConnectionAttr.STATUS).set(ConnectStatus.CLOSE);
        log.debug(String.format("客户端处于CLOSE状态, remoteAddress:[%s]", ctx.channel().remoteAddress()));
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        //根据移除connectionGroup中的注册信息
        Optional.ofNullable(ctx.channel())
                .map(channel -> channel.attr(ConnectionAttr.MAC).get())
                .ifPresent(connectionGroup::del);
        super.handlerRemoved(ctx);
        log.debug(String.format("客户端通道已被移除, remoteAddress:[%s]", ctx.channel().remoteAddress()));
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        //触发空闲事件后,直接关闭通道
        if (evt instanceof IdleStateEvent) {
            log.debug(String.format("客户端触发空闲事件, remoteAddress:[%s]", ctx.channel().remoteAddress()));
            ctx.disconnect();
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }
}